#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QDragEnterEvent>
#include <QDropEvent>
#include <QFileDialog>
#include <QMimeData>
#include <QSettings>
#include <QThread>

#include "deluacore.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    task(new DeluacCore())
{
    ui->setupUi(this);

    resize(640, 480);
    setAcceptDrops(true);

    ini = qApp->applicationDirPath() + "/deluac.ini";
    auto cfg = std::make_shared<QSettings>(ini, QSettings::Format::IniFormat);
    QString xxteaSign = cfg->value("xxtea-sign", "请输入正确的XXTEA签名").toString();
    QString xxteaKey = cfg->value("xxtea-key", "请输入正确的XXTEA密钥").toString();
    QString searchPath = cfg->value("search-path", "请输入要批量解密的文件夹").toString();
    QString srcExtension = cfg->value("src-extension", "luac").toString();
    QString destExtension = cfg->value("dest-extension", "lua").toString();
    ui->txtXxteaSign->setText(xxteaSign);
    ui->txtXxteaKey->setText(xxteaKey);
    ui->txtSearchPath->setText(searchPath);
    ui->txtSrcExt->setText(srcExtension);
    ui->txtDestExt->setText(destExtension);

    qRegisterMetaType<DeluacState>("DeluacState");
    connect(task, &DeluacCore::decryptCompleted, this, &MainWindow::decryptCompleted);
    connect(task, &DeluacCore::guessCompleted, this, &MainWindow::guessCompleted);
    connect(task, &DeluacCore::started, this, [this]()
    {
        ui->btnDecryptFile->setEnabled(false);
        ui->btnGuessSignKey->setEnabled(false);
    });
    connect(task, &DeluacCore::finished, this, [this]()
    {
        on_txtSearchPath_textChanged(ui->txtSearchPath->text());
    });
    auto textChanged = [this](const QString &) {
        auto isSameExt = (ui->txtSrcExt->text() == ui->txtDestExt->text());
        ui->rbKeepFile->setEnabled(!isSameExt);
        ui->rbMoveFile->setEnabled(!isSameExt);
        if (isSameExt) {
            ui->rbKeepFile->setChecked(true);
        }
    };
    connect(ui->txtSrcExt, &QLineEdit::textChanged, textChanged);
    connect(ui->txtDestExt, &QLineEdit::textChanged, textChanged);
    textChanged(QString());
    ui->txtSrcExt->setAttribute(Qt::WA_InputMethodEnabled, false);
    ui->txtDestExt->setAttribute(Qt::WA_InputMethodEnabled, false);
}

MainWindow::~MainWindow()
{
    if (task->isRunning())
        task->wait();

    delete task;
    delete ui;
}

void MainWindow::dragEnterEvent(QDragEnterEvent *event)
{
    QString path = event->mimeData()->urls().first().toLocalFile();
    if (QFileInfo(path).isDir())
        event->acceptProposedAction();
}

void MainWindow::dropEvent(QDropEvent *event)
{
    QString path = event->mimeData()->urls().first().toLocalFile();
    ui->txtSearchPath->setText(path.replace("/", QDir::separator()));
}

void MainWindow::fetchDeluacArgs(DeluacArgs &args)
{
    auto cfg = std::make_shared<QSettings>(ini, QSettings::Format::IniFormat);
    cfg->setValue("xxtea-sign", ui->txtXxteaSign->text());
    cfg->setValue("xxtea-key", ui->txtXxteaKey->text());
    cfg->setValue("search-path", ui->txtSearchPath->text());
    cfg->setValue("src-extension", ui->txtSrcExt->text());
    cfg->setValue("dest-extension", ui->txtDestExt->text());

    args =
    {
        ui->txtSearchPath->text(),
        ui->txtXxteaSign->text(),
        ui->txtXxteaKey->text(),
        ui->txtSrcExt->text(),
        ui->txtDestExt->text()
    };
}

void MainWindow::on_btnBrowseDir_clicked()
{
    QString folder = QFileDialog::getExistingDirectory();
    ui->txtSearchPath->setText(folder.replace("/", QDir::separator()));

    // FOR /R %i IN (*.lua) DO REN %i *.luac
}

void MainWindow::on_btnGuessSignKey_clicked()
{
    if (!task->isRunning())
    {
        DeluacArgs args;
        fetchDeluacArgs(args);
        task->startGuess(args);
    }
}

void MainWindow::on_btnDecryptFile_clicked()
{
    if (!task->isRunning())
    {
        DeluacArgs args;
        fetchDeluacArgs(args);
        ui->txtLogger->clear();
        task->startDecrypt(args);
    }
}

void MainWindow::on_txtSearchPath_textChanged(const QString &text)
{
    if (!task->isRunning())
    {
        ui->btnDecryptFile->setEnabled(QFile::exists(text));
        ui->btnGuessSignKey->setEnabled(QFile::exists(QString("%1%2lib").arg(text).arg(QDir::separator())));
    }
}

void MainWindow::decryptCompleted(const QString &filePath, DeluacState state, int progressValue)
{
    switch (state)
    {
    case DeluacState::Failed:
    {
        ui->txtLogger->append(filePath + " <span style='color:blue'>--></span> <span style='color:red;'>" + "解密失败" + "</span>");
    }
        break;
    case DeluacState::Succeed:
    {
        ui->txtLogger->append(filePath + " <span style='color:blue'>--></span> <span style='color:green;'>" + "解密成功" + "</span>");
        if (ui->rbMoveFile->isChecked() && !QFile(filePath).remove())
        {
            ui->txtLogger->append(filePath + " <span style='color:blue'>--></span>  <span style='color:red;'>" + "删除失败" + "</span>");
        }
    }
        break;
    default:
    {
        ui->txtLogger->append(filePath + " <span style='color:blue'>--></span> <span style='color:blue;'>" + "文件未加密" + "</span>");
        if (ui->rbMoveFile->isChecked() && !QFile(filePath).remove())
        {
            ui->txtLogger->append(filePath + " <span style='color:blue'>--></span>  <span style='color:red;'>" + "删除失败" + "</span>");
        }
    }
        break;
    }
    ui->pbDecryptFile->setValue(progressValue);
}

void MainWindow::guessCompleted(const QString &xxteaSign, const QString &xxteaKey)
{
    ui->txtXxteaSign->setText(xxteaSign);
    ui->txtXxteaKey->setText(xxteaKey);
}
